package com.didd.core.common.base;

import lombok.AllArgsConstructor;
import lombok.Setter;
import lombok.ToString;

/**
 * dubbo返回的异常定义枚举
 * 自定义子类异常code复用业务异常码
 * 例：业务异常 1000, 自定义业务异常为1001-1999之间
 *
 * @author diddd
 * @date 2019/06/26
 */
@ToString
@AllArgsConstructor
public enum ResultCode implements ResultStatus {

    /**
     * 请求成功
     */
    SUCCESS(0, "SUCCESS", "success"),
    /**
     * 业务异常
     */
    FAIL_BIZ(1000, "FAIL_BIZ", "biz exception"),
    /**
     * 已存在数据
     */
    FAIL_BIZ_EXISTED(2000, "FAIL_BIZ_EXISTED", "data existed error"),
    /**
     * 数据未找到
     */
    FAIL_BIZ_NOT_FOUND(3000, "FAIL_BIZ_NOT_FOUND", "data not found error"),
    /**
     * 请求参数错误
     */
    FAIL_BIZ_PARAMETER(4000, "FAIL_BIZ_PARAMETER", "request parameter error"),
    /**
     * 未知异常
     */
    FAIL_UNKNOWN(1, "FAIL_UNKNOWN", "system error"),
    /**
     * 网络异常
     */
    FAIL_NETWORK(2, "FAIL_NETWORK", "network error"),
    /**
     * 请求超时
     */
    FAIL_TIMEOUT(3, "FAIL_TIMEOUT", "request timeout"),
    /**
     * 禁止访问
     */
    FAIL_FORBIDDEN(4, "FAIL_FORBIDDEN", "forbidden error"),
    /**
     * 序列化异常
     */
    FAIL_SERIALIZATION(5, "FAIL_SERIALIZATION", "serializable error"),
    /**
     * 未知实例调用
     */
    FAIL_NO_INVOKER_AVAILABLE_AFTER_FILTER(6, "FAIL_NO_INVOKER_AVAILABLE_AFTER_FILTER", "no invoker available after filter"),
    /**
     * Redis分布式锁等待
     */
    REDIS_LOCK_WAIT(7, "REDIS_LOCK_WAIT", "操作过于频繁,请求正在处理中...");

    /**
     * return code
     */
    private int code;
    /**
     * return status
     */
    private String status;
    /**
     * return warning
     */
    @Setter
    private String message;


    @Override
    public int fetchCode() {
        return this.code;
    }

    @Override
    public String fetchStatus() {
        return this.status;
    }

    @Override
    public String fetchMessage() {
        return this.message;
    }

    /**
     * 异常code获取枚举
     *
     * @param code 异常code
     * @return {@link ResultStatus}
     */
    public static ResultStatus fetchByCode(int code) {
        // 异常分界值
        final int cutoffValue = 3;
        // 替换dubbo定义异常为自定义异常
        if (code < cutoffValue) {
            code = code + 1;
        }
        for (ResultStatus status : ResultCode.values()) {
            if (status.fetchCode() == code) {
                return status;
            }
        }
        return ResultCode.FAIL_UNKNOWN;
    }
}
